﻿using System;
using System.Collections.Generic;
using System.Linq;
using JasLib.Extensions;

namespace JasLib.Collections
{
    public class ObservableSortableList<T> : SimplifiedListBase<T>
    {
        //System.Windows.Data.Binding.IndexerName;
        private static readonly T[] s_emptyArray = Enumerable.Empty<T>().AsArray();
        private T[] _items = null;
        private int _iStartingOffset = 0;
        private int _iEndingOffset = 0;

        private Comparison<T> _comparison = null;
        public Comparison<T> Comparison
        {
            get { return _comparison; }
            set
            {
                if (_comparison != value)
                {
                    if (value != null)
                    {
                        Array.Sort(_items, _iStartingOffset, this.Count, new ComparisonToComparer<T>(value));
                    }

                    _comparison = value;
                }
            }
        }

        private bool _bUniqueSortedElements = true;

        public ObservableSortableList()
            : this(1, null, false)
        {
        }

        public ObservableSortableList(int iCapacity = 1, Comparison<T> comparison = null, bool bUniqueSortedElements = true)
        {
            //System.Collections.ObjectModel.ObservableCollection<int>
            //List<T>
        }

        public ObservableSortableList(
            IEnumerable<T> source,
            Comparison<T> comparison = null,
            bool bUniqueSortedElements = true)
        {
            _items = source.ToArray();
            _iStartingOffset = 0;
            _iEndingOffset = _items.Length;

            return;
        }

        public void Compact()
        {
            int iCount = this.Count;
            if (iCount != _items.Length)
            {
                var items = new T[iCount];
                Array.Copy(_items, _iStartingOffset, items, 0, iCount);
                _iStartingOffset = 0;
                _iEndingOffset = iCount;
            }
            return;
        }

        public void Normalize()
        {
            if (_iStartingOffset != 0)
            {
                int iCount = this.Count;
                Array.Copy(_items, _iStartingOffset, _items, 0, iCount);
                _iStartingOffset = 0;
                _iEndingOffset = iCount;
            }
            return;
        }

        public Tuple<T[], int, int> Extract()
        {
            var tuple = Tuple.Create(_items, _iStartingOffset, this.Count);
            _items = s_emptyArray;
            _iStartingOffset = 0;
            _iEndingOffset = 0;
            return tuple;
        }

        public override void Add(T item)
        {
            if (_comparison != null)
            {
            }
            else
            {
            }

            return;
        }

        public override void Insert(int index, T item)
        {
            if (_comparison != null)
                throw new InvalidOperationException();

            return;
        }

        public override bool Remove(T item)
        {
            return false;
        }

        public override void RemoveAt(int index)
        {
            RemoveRange(index, 1);
            return;
        }

        public override int Count
        {
            get
            {
                return (_iEndingOffset - _iStartingOffset);
            }
        }

        public void InsertRange(int iIndex, IEnumerable<T> source)
        {
            if (_comparison != null)
                throw new InvalidOperationException();

            return;
        }

        public void RemoveRange(int iStartingIndex, int iCount)
        {
        }

        public void MoveRange(int iSourceIndex, int iDestinationIndex, int iCount)
        {
            if (_comparison != null)
                throw new InvalidOperationException();

            return;
        }
    }
}
